﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Threading;
using Microsoft.PowerShell.CmdletManagement;
using System.Collections.ObjectModel;
using System.Collections;
using System.Configuration;

namespace Microsoft.PowerShell.CmdletManagement
{
    
    /// <summary>
    /// Interaction logic for NewProject.xaml
    /// </summary>
    public partial class NewProject : System.Windows.Window
    {

        public NewProject(string serviceUri, Window owner)
        {
            InitializeComponent();
            this.serviceUri = serviceUri;
            this.Owner = owner;
                        
            Thread t = new Thread(new ThreadStart(GetProjects));
            t.IsBackground = true;
            t.Start();
        }

        private string serviceUri;
        private List<PsSpecProject> projects;

        delegate void UpdateProjectsDelegate();

        private void GetProjects()
        {
            RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
            PSSnapInException warning;

            try
            {
                rsConfig.AddPSSnapIn("PsSpecCmdletManagement", out warning);
            }
            catch (PSArgumentException exc)
            {
                string title = "Count not add snapin";
                string context = "Could not execute command because the PsSpecCmdletManagement snapin is not installed.";

                CmdletDesignerUtils.HandleException(title, context, exc);
                return;
            }

            Runspace runspace = RunspaceFactory.CreateRunspace(rsConfig);
            runspace.Open();
            System.Collections.IEnumerable pipelineResults = new Object[0];
            List<PsSpecProject> results = new List<PsSpecProject>();

            // get only projects I own for edit.
            String UserIdentity = System.Security.Principal.WindowsIdentity.GetCurrent().Name; 

            // PS> Get-PsSpecUserPermission -ServiceUri $uri | where {$_.User -eq "DOMAIN\user" -and $_.Role -eq "ProjectOwner"} `
            //    | foreach {get-Psspecproject -name $_.Project -ServiceUri $uri}
            string pipelineCommand = "Get-PsSpecUserPermission -ServiceUri " + serviceUri + " | where {$_.User -eq \"" + UserIdentity + "\" -and  $_.Role -eq \"ProjectOwner\"} | foreach {get-Psspecproject -name $_.Project -ServiceUri " + serviceUri+ "}";             
            Pipeline pipeline = runspace.CreatePipeline(pipelineCommand);
                           
            try
            {
                pipelineResults =  pipeline.Invoke();
                foreach (PSObject result in pipelineResults)
                {
                    PsSpecProject proj = new PsSpecProject();
                    proj.Name = (string)result.Members["Name"].Value;
                    proj.Owner = (string)result.Members["Owner"].Value;
                    proj.Id = (int)result.Members["Id"].Value;
                    proj.Description = (string)result.Members["Description"].Value;

                    results.Add(proj);
                }
            }
            catch (Exception exception)
            {
                CmdletDesignerUtils.HandleException("Error loading projects",
                    "There were errors loading the list of projects.",
                    exception);
            }

            projects = results;

            Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new UpdateProjectsDelegate(UpdateProjectsNameAndDescription));
        }

        private void UpdateProjectsNameAndDescription()
        {
            this.ProjectList.DataContext = projects;
            ProgressIndicator.Visibility = Visibility.Hidden;
        }

        public string ProjectName
        {
            get
            {
                String projectName = (String)this.NameBlock.Value;

                if (projectName == null)
                    return null;
                else
                    return (string)projectName;
            }
        }

        public string ProjectOwner
        {
            get
            {
                String owner = (String)this.ProjectAdmin.Value;

                if (owner == null)
                    return null;
                else
                    return (string)owner;
            }
        }

        public string ProjectDescription
        {
            get
            {
                String projectDescription = (String)this.Description.Value;

                if (projectDescription == null)
                    return null;
                else
                    return (string)projectDescription;
            }
        }

        public int ProjectId
        {
                
            get
            {

                    int int32Val;
                    int projectId = -1;
                    string id = (string)this.Id.Value;
                    if (id == null)
                    {
                        return -1;
                    }
                    else
                    {

                        bool Convertuccess = int.TryParse(id, out int32Val);
                        if (Convertuccess)
                        {
                            projectId = int32Val;
                        }

                        return projectId;
                    }
            }
        }

        private void DoubleClick_SelectProjectToUpdate(Object sender, MouseButtonEventArgs e)
        {
            PopulateUpdateProjectTextFields();
        }

        private void PopulateUpdateProjectTextFields()
        {
            if (this.ProjectList.SelectedItems.Count > 0)
            {
                Application.Current.Properties["SelectedProject"] = this.ProjectList.SelectedItem;
                this.DataContext = this.ProjectList.SelectedItem;
            }
        }

        // They've clicked "OK"
        private void Click_Ok(Object sender, RoutedEventArgs e)
        {
            UpdatedProject(this.ProjectName, this.ProjectOwner, this.ProjectDescription,this.ProjectId);
            this.DialogResult = true;
            this.Close();
        }

        private void UpdatedProject(String ProjectName, String Owner, String Description, Int32 ProjId)
        {
            RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
            PSSnapInException warning;

            try
            {
                rsConfig.AddPSSnapIn("PsSpecCmdletManagement", out warning);
            }
            catch (PSArgumentException exc)
            {
                string title = "Count not add snapin";
                string context = "Could not execute command because the PsSpecCmdletManagement snapin is not installed.";

                CmdletDesignerUtils.HandleException(title, context, exc);
                return;
            }

            Runspace runspace = RunspaceFactory.CreateRunspace(rsConfig);
            runspace.Open();
            
            if ((ProjId > -1))
            {
                using (Pipeline pipeline = runspace.CreatePipeline())
                {
                    Command updateProject = new Command("Set-PsSpecProject");
                    updateProject.Parameters.Add("ServiceUri", serviceUri);
                    updateProject.Parameters.Add("Id", ProjId);
                    updateProject.Parameters.Add("Name", ProjectName);
                    updateProject.Parameters.Add("Description", ProjectDescription);
                    pipeline.Commands.Add(updateProject);
                    pipeline.Invoke();
                    
                }
            }
            else
            {
                using (Pipeline pipeline = runspace.CreatePipeline())
                {
                    Command updateProject = new Command("New-PsSpecProject");
                    updateProject.Parameters.Add("ServiceUri", serviceUri);
                    updateProject.Parameters.Add("Name", ProjectName);
                    updateProject.Parameters.Add("Description", ProjectDescription);
                    pipeline.Commands.Add(updateProject);
                    if (ProjectName != null)
                    {
                        pipeline.Invoke();
                    }
                    else
                    {
                        MessageBox.Show("Please make sure to enter a valid project name!", "Null or empty project name.", MessageBoxButton.OK, MessageBoxImage.Warning);
                    }

                }

            }
        }


        // They've clicked "Cancel"
        private void Click_Cancel(Object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            this.Close();
        }

        //  Refresh the view when data is loaded
        private void Project_Loaded(Object sender, EventArgs e)
        {
            ICollectionView collectionView = ProjectCollectionView;
            if (collectionView != null) { collectionView.Refresh(); }
        }


        private ICollectionView ProjectCollectionView
        {
            get
            {
                if (ProjectCollectionView == null)
                {
                    lock (lockObject)
                    {
                        if (ProjectCollectionView == null)
                        {
                            if (ProjectCollectionView != null)
                            {                              
                                ProjectCollectionView.SortDescriptions.Clear();
                                SortDescription sd = new SortDescription("ProjectName", ListSortDirection.Ascending);
                                ProjectCollectionView.SortDescriptions.Add(sd);
                                ProjectCollectionView.Refresh();
                            }
                        }
                    }
                }

                return ProjectCollectionView;
            }
        }

        private object lockObject = new object();

     
    }
}